import 'dart:developer';

import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:flutter_sound/public/flutter_sound_player.dart';
import 'package:get/get.dart';
import 'package:im_base/private/app_ext.dart';
import 'package:im_base/public/global/custom_bean.dart';
import 'package:im_base/public/global/global.dart';
import 'package:im_base/public/global/im_keys.dart';
import 'package:im_base/public/service/tim_service.dart';
import 'package:im_base/public/tim/components/chat/logic.dart';
import 'package:tencent_im_sdk_plugin/enum/V2TimAdvancedMsgListener.dart';
import 'package:tencent_im_sdk_plugin/enum/V2TimConversationListener.dart';
import 'package:tencent_im_sdk_plugin/enum/V2TimFriendshipListener.dart';
import 'package:tencent_im_sdk_plugin/enum/group_member_filter_enum.dart';
import 'package:tencent_im_sdk_plugin/enum/group_member_filter_type.dart';
import 'package:tencent_im_sdk_plugin/enum/message_elem_type.dart';
import 'package:tencent_im_sdk_plugin/manager/v2_tim_manager.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_callback.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_conversation.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_group_info.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_group_info_result.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_group_member_info_result.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_group_search_param.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_message.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_value_callback.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_user_full_info.dart';
import 'package:im_base/public/ext/string_ext.dart';
import 'package:logger/logger.dart';

///腾讯云IM初始化及常用操作
class InitService extends GetxService {
  V2TIMManager? v2timManager;
  String? currentUser;
  FlutterSoundPlayer? _player;

  @override
  void onInit() {
    super.onInit();
  }

  void initSDK() async {
    v2timManager = TimService.instance.v2timManager;
    log("----$v2timManager");
  }

  void login(String id, String sign) {
    currentUser = id;
    Global.IDENTIFIER = id;

    ///防止多次添加监听导致收发消息重复,每次登陆之前先移除消息监听
    v2timManager?.v2TIMMessageManager.removeAdvancedMsgListener();
    v2timManager?.login(userID: id, userSig: sign).then((res) {
      if (res.code == 0) {
        ///IM登录成功之后再获取用户信息
        loginIMSuccess();

        ///监听消息收发
        _registerNewMessages();
        _watchConversation();
        _watchFriendChange();
      } else {
        ///如果登录失败,则退出,让用户重新进行登录
        reLogin();
        showToast("登录腾讯云失败:${res.code}|${res.desc}");
      }
    });
  }

  ///监听好友信息变更,如果备注有变更,则同步更新会话列表
  void _watchFriendChange() {
    v2timManager!.getFriendshipManager().setFriendListener(
        listener: V2TimFriendshipListener(onFriendInfoChanged: (info) {
      writeIMData(IMKeys.friendInfoChange, info);
    }));
  }

  ///监听会话列表变动
  void _watchConversation() {
    v2timManager?.getConversationManager().setConversationListener(
            listener:
                V2TimConversationListener(onNewConversation: (conversation) {
          if (conversation.isNotEmpty) {
            var admin =
                conversation.where((element) => element.userID == 'admin');
            if (admin.isNotEmpty) {
              if (shouldMarkRead(admin.first)) {
                markMessageRead(admin.first);
                _registerUnread(0);
              }
            } else {
              _registerUnread(0);
            }
            writeIMData(IMKeys.conversationList, conversation);
          }
        }, onConversationChanged: (conversation) {
          if (conversation.isNotEmpty) {
            var admin =
                conversation.where((element) => element.userID == 'admin');
            if (admin.isNotEmpty) {
              if (shouldMarkRead(admin.first)) {
                markMessageRead(admin.first);
                _registerUnread(0);
              }
            } else {
              _registerUnread(0);
            }
            // shouldPinned(conversation);
            writeIMData(IMKeys.conversationList, conversation);
          }
        }));
  }

  ///admin账号发送的消息是否需要标记为已读状态,这里是过滤规则
  bool shouldMarkRead(V2TimConversation conversation) {
    log('shouldMarkRead----${conversation.toJson()}');
    final lastMsg = conversation.lastMessage;
    if (lastMsg == null) {
      return true;
    }
    if (lastMsg.customElem == null) {
      return true;
    }
    final msgContent = lastMsg.customElem!.data!.isEmpty
        ? lastMsg.customElem!.desc!.isEmpty
            ? lastMsg.customElem!.extension!.isEmpty
                ? lastMsg.customElem!.extension!
                : lastMsg.customElem!.data!
            : lastMsg.customElem!.desc!
        : lastMsg.customElem!.extension!;
    if ((msgContent.contains('caseInfo') ||
        msgContent.contains('patOverWordInquiry'))) {
      ///如果是问诊病历信息或者是患者结束问诊消息,则不标记已读
      return false;
    }
    return true;
  }

  void shouldPinned(List<V2TimConversation> conversation) {
    conversation.forEach((element) {
      log('shouldPinned----${DateTime.now()}---${element.isPinned}---${element.toJson()}');
      final lastMsg = element.lastMessage;
      if (lastMsg != null && lastMsg.customElem != null) {
        final msgContent = lastMsg.customElem!.extension!;
        if (msgContent.contains('caseInfo')) {
          element.isPinned = false;
          if(element.unreadCount==0){
            element.unreadCount=1;
          }
        }
        if ((msgContent.contains('patOverWordInquiry') ||
            msgContent.contains('docOverWordInquiry'))) {
          element.isPinned = true;
        }
      }
    });
  }

  void _registerUnread(int count) async {
    Future.delayed(const Duration(milliseconds: 500), () async {
      await v2timManager?.v2ConversationManager
          .getTotalUnreadMessageCount()
          .then((value) => getUnreadCount((value.data ?? 0) - count));
    });
  }

  ///将未读数抛出
  void getUnreadCount(int count) {}

  ///监听消息收发
  void _registerNewMessages() {
    v2timManager?.v2TIMMessageManager.addAdvancedMsgListener(
        listener: V2TimAdvancedMsgListener(onRecvNewMessage: (newMessage) {
      ///新消息接收
      ///收到消息之后重新获取未读数量,如果发送消息为admin则不作提示,且将该会话删除
      if (newMessage.userID == 'admin') {
        // deleteConversationById(newMessage.userID ?? '', (p0) => {});
      } else {
        allMessage(newMessage);
      }

      ///如果是自定义消息,则单独处理,筛选之后进行展示
      ///如果是非自定义消息,则直接展示消息
      if (newMessage.elemType == MessageElemType.V2TIM_ELEM_TYPE_CUSTOM) {
        customReceive(newMessage);
      } else {
        commonReceive(newMessage);
      }

      ///将新消息写入内存,使用会话id作为key,防止监听消息错乱
      if (Get.isRegistered<ChatLogic>(
          tag: newMessage.userID ?? newMessage.groupID)) {
        ///如果当前不再聊天页面,则不再进行通知
        writeIMData(
            newMessage.userID ?? newMessage.groupID ?? "empty", newMessage);
      }
    }, onSendMessageProgress: (message, progress) {
      ///发送消息进度回调
      log('onSendMessageProgress---$progress');
      message.progress = progress;
      writeIMData(IMKeys.sendMsgProgress, message);
    }, onRecvMessageRevoked: (message) {
      ///对方撤回消息回调
      writeIMData(IMKeys.withdrawMessage, message);
    }));
  }

  ///更新自己腾讯云用户信息
  ///将自己的个人信息维护到腾讯自定义数据中
  void updateInfo(
      {String? userName,
      String? header,
      int? gender,
      String? userID,
      String? hosName,
      String? hosID,
      String? deptID,
      String? deptName}) {
    v2timManager?.setSelfInfo(
        userFullInfo: V2TimUserFullInfo(
            userID: currentUser,
            faceUrl: header,
            nickName: userName,
            customInfo: {
              'userId': userID ?? '',
              'hosName': hosName ?? '',
              'hosId': hosID ?? '',
              'deptId': deptID ?? '',
              'deptName': deptName ?? ''
            },
            gender: gender));
  }

  void logoutIM() {
    v2timManager?.v2TIMMessageManager.removeAdvancedMsgListener();
    v2timManager?.logout();
  }

  ///腾讯云IM登录成功
  ///登录成功之后先加载会话列表,同时监听会话列表的变动,监听自定义消息事件
  ValueSetter? loginSuccess;
  ValueSetter? customMessageClickCallBack;

  void loginIMSuccess() {
    if (loginSuccess == null) {
      loginSuccess = (data) {
        if (data) {
          reLogin();
        }
      };
    }
    if (customMessageClickCallBack == null) {
      customMessageClickCallBack = (data) => customMessageClick(data);
    }
    watchIMData(IMKeys.kickOut, loginSuccess!);
    watchIMData(IMKeys.customMessageClick, customMessageClickCallBack!);
  }

  ///登录过期或者账号被踢掉
  void reLogin() {
    showToast("您的账号已在其他地方登录");
    logoutIM();
  }

  ///根据会话id删除会话
  void deleteConversationById(String conID, Function(String) onSuccess) async {
    await v2timManager!
        .getConversationManager()
        .deleteConversation(conversationID: conID)
        .then((value) {
      if (value.code == 0) {
        onSuccess(conID);
      } else {
        showToast('删除失败:[${value.code}]:${value.desc}');
      }
    });
  }

  ///根据会话标记已读
  void markMessageRead(V2TimConversation conversation) async {
    log('markMessageRead-------------${conversation.conversationID}');
    if (!conversation.groupID.isNullEmpty()) {
      markMessageReadById(conversation.groupID!, true);
    } else if (!conversation.userID.isNullEmpty()) {
      markMessageReadById(conversation.userID!, false);
    }
  }

  ///根据id标记会话已读
  void markMessageReadById(String id, bool isGroup) async {
    log('markMessageReadById-------------$id');
    if (isGroup) {
      v2timManager!
          .getMessageManager()
          .markGroupMessageAsRead(groupID: id)
          .then((value) {
        markReadResult(value.code);
      });
    } else {
      v2timManager!
          .getMessageManager()
          .markC2CMessageAsRead(userID: id)
          .then((value) {
        markReadResult(value.code);
      });
    }
  }

  ///标记消息已读的回调结果
  void markReadResult(int code) {}

  ///发送自定义消息
  void sendCustomMessage(String content,
      {required String id,
      required bool isGroup,
      bool? excludedUnread,
      Function(V2TimValueCallback<V2TimMessage>)? callBack}) async {
    if (id.isNullEmpty()) {
      showToast("账号信息有误");
      return;
    }
    var result = await v2timManager!.v2TIMMessageManager
        .createCustomMessage(data: content, extension: content);
    await v2timManager!.v2TIMMessageManager
        .sendMessage(
            id: result.data?.id ?? '',
            receiver: isGroup ? '' : id,
            groupID: isGroup ? id : '')
        .then((value) {
      if (value.code == 0 && value.data != null) {
        if (Get.isRegistered<ChatLogic>(tag: id)) {
          Get.find<ChatLogic>(tag: id).addNewMessage(value.data!);
        }
      }
      callBack?.call(value);
      onSendMessage(value);
    });
  }

  ///发送文字消息
  void sendTextMessage(String content,
      {required String id,
      required bool isGroup,
      Function(V2TimValueCallback<V2TimMessage>)? callBack}) async {
    if (id.isNullEmpty()) {
      showToast("账号信息有误");
      return;
    }
    var result = await v2timManager!.v2TIMMessageManager
        .createTextMessage(text: content);
    await v2timManager!.v2TIMMessageManager
        .sendMessage(
            id: result.data?.id ?? '',
            receiver: isGroup ? '' : id,
            groupID: isGroup ? id : '')
        .then((value) {
      callBack?.call(value);
      onSendMessage(value);
    });
  }

  ///发送图片消息
  void sendImageMessage(String path, String id, bool isGroup,
      {Function(V2TimValueCallback<V2TimMessage>)? callBack}) async {
    var result = await v2timManager!.v2TIMMessageManager
        .createImageMessage(imagePath: path);
    await v2timManager!.v2TIMMessageManager
        .sendMessage(
            id: result.data?.id ?? '',
            receiver: isGroup ? "" : id,
            groupID: isGroup ? id : "")
        .then((value) {
      callBack?.call(value);
      onSendMessage(value);
    });
  }

  ///发送语音消息
  void sendAudioMessage(String path, int timeLength, String id, bool isGroup,
      {Function(V2TimValueCallback<V2TimMessage>)? callBack}) async {
    var result = await v2timManager!.v2TIMMessageManager
        .createSoundMessage(soundPath: path, duration: timeLength);
    await v2timManager!.v2TIMMessageManager
        .sendMessage(
            id: result.data?.id ?? '',
            receiver: isGroup ? "" : id,
            groupID: isGroup ? id : "")
        .then((value) {
      callBack?.call(value);
      onSendMessage(value);
    });
  }

  ///删除消息
  void deleteMessage(String msgId, {Function(V2TimCallback)? callBack}) async {
    await v2timManager!
        .getMessageManager()
        .deleteMessageFromLocalStorage(msgID: msgId)
        .then((value) {
      if (callBack != null) callBack(value);
    });
  }

  ///撤回消息
  void withDrawMessage(String msgId,
      {Function(V2TimCallback)? callBack}) async {
    await v2timManager!
        .getMessageManager()
        .revokeMessage(msgID: msgId)
        .then((value) => callBack);
  }

  ///获取群信息
  Future<V2TimValueCallback<List<V2TimGroupInfoResult>>> getGroupInfo(
      String groupId) async {
    return v2timManager!
        .getGroupManager()
        .getGroupsInfo(groupIDList: [groupId]);
  }

  ///获取群成员列表
  Future<V2TimValueCallback<V2TimGroupMemberInfoResult>> getGroupMember(
      String groupId, String nextSeq) async {
    return v2timManager!.getGroupManager().getGroupMemberList(
        groupID: groupId,
        filter: GroupMemberFilterTypeEnum.V2TIM_GROUP_MEMBER_FILTER_ALL,
        nextSeq: nextSeq);
  }

  ///修改群信息
  Future<V2TimCallback> modifyGroupName(String groupId, String groupType,
      {String? groupName, String? introduce, String? faceUrl}) async {
    return v2timManager!.getGroupManager().setGroupInfo(
        info: V2TimGroupInfo(
            groupID: groupId,
            groupType: groupType,
            groupName: groupName,
            faceUrl: faceUrl,
            introduction: introduce));
  }

  ///修改群成员信息
  Future<V2TimCallback> modifyGroupMember(
      String groupId, String userId, String nameCard) async {
    return v2timManager!.getGroupManager().setGroupMemberInfo(
        groupID: groupId, userID: userId, nameCard: nameCard);
  }

  ///获取群成员信息
  Future<V2TimValueCallback<List<V2TimGroupMemberFullInfo>>> getMemberInfo(
      String groupId, List<String> ids) async {
    return v2timManager!
        .getGroupManager()
        .getGroupMembersInfo(groupID: groupId, memberList: ids);
  }

  ///解除/禁言用户
  Future<V2TimCallback> manageMute(String groupID, String userID,
      {int? seconds}) async {
    return v2timManager!.getGroupManager().muteGroupMember(
        groupID: groupID,
        userID: userID,
        seconds: seconds ?? 30 * 24 * 60 * 60);
  }

  ///踢出用户
  Future<V2TimCallback> kickoutUser(String groupID, List<String> userID,
      {int? seconds}) async {
    return v2timManager!
        .getGroupManager()
        .kickGroupMember(groupID: groupID, memberList: userID);
  }

  ///退出群聊
  Future<V2TimCallback> exitGroup(String groupId) async {
    var result = await v2timManager!.quitGroup(groupID: groupId);
    if (result.code == 0) {
      writeIMData(IMKeys.deleteConversation, groupId);
    }
    return result;
  }

  ///解散群聊
  Future<V2TimCallback> destoryGroup(String groupId) async {
    var result = await v2timManager!.dismissGroup(groupID: groupId);
    if (result.code == 0) {
      writeIMData(IMKeys.deleteConversation, groupId);
    }
    return result;
  }

  ///根据群名称搜索群列表
  Future<V2TimValueCallback<List<V2TimGroupInfo>>> searchGroup(
      String groupName) async {
    return await v2timManager!.v2TIMGroupManager.searchGroups(
        searchParam: V2TimGroupSearchParam(keywordList: [groupName]));
  }

  ///所有消息接收事件
  void allMessage(V2TimMessage newMessage) {}

  ///自定义消息接收事件
  void customReceive(V2TimMessage newMessage) {}

  ///普通消息接收事件
  void commonReceive(V2TimMessage newMessage) {}

  ///自定义消息点击事件
  void customMessageClick(CustomBean bean) {}

  ///将发送消息的事件抛出
  void onSendMessage(V2TimValueCallback<V2TimMessage> value) {
    log('onSendMessage---$value');
    writeIMData(IMKeys.SEND_MESSAGE, value.code == 0);
  }

  var bytes;

  ///播放新收到消息提示音
  void playNewMessage() async {
    if (_player == null) {
      _player = FlutterSoundPlayer();
      _player!.setLogLevel(Level.nothing);
      await _player
          ?.openAudioSession()
          .then((value) => value?.dispositionStream()?.listen((event) {
                log('FlutterSoundPlayer--${event.duration.inSeconds}--${event.position}');
              }));
    }
    if (bytes == null) {
      bytes = await rootBundle.load("assets/files/new_message.mp3");
    }
    log('playSound----');
    _player?.startPlayer(fromDataBuffer: bytes.buffer.asUint8List());
  }

  var ringBytes;

  ///播放视频问诊铃声
  void playRing() async {
    if (_player == null) {
      _player = FlutterSoundPlayer();
      _player!.setLogLevel(Level.nothing);
      await _player
          ?.openAudioSession()
          .then((value) => value?.dispositionStream()?.listen((event) {
                log('FlutterSoundPlayer--${event.duration.inSeconds}--${event.position}');
              }));
    }
    if (ringBytes == null) {
      ringBytes = await rootBundle.load("assets/files/avchat_ring.mp3");
    }
    if (_player!.isPlaying) {
      ///如果正在播放铃声,则不再重复播放
      return;
    }
    log('playSound----');
    _player?.startPlayer(fromDataBuffer: ringBytes.buffer.asUint8List());
  }

  ///停止播放音频
  void stopPlay() {
    _player?.stopPlayer();
  }
}
